//
//  YWDownloadDataTaskStatus2.m
//  videoTest3
//
//  Created by jun peng on 2022/7/28.
//

#import "YWDownloadDataTaskStatus2.h"

@interface YWDownloadDataTaskStatus2 ()<NSURLSessionDataDelegate>

//由status里面属性fullPath产生、不需要保存到本地
@property (nonatomic, strong) NSFileHandle *handle;

//当你进入下载页面、传入status进来我就创建一个由新的session创建一个新的任务
@property (nonatomic, strong)  NSURLSessionDataTask *dataTask;

/* AFURLSessionManager */
@property (nonatomic, strong) AFURLSessionManager *manager;


@end

@implementation YWDownloadDataTaskStatus2


- (AFURLSessionManager *)manager {

    if (!_manager) {
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        
        // 1. 创建会话管理者
        _manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
        
        AFHTTPResponseSerializer *serializer = [AFHTTPResponseSerializer serializer];
        
        serializer.acceptableContentTypes = [NSSet setWithObjects:@"video/mp4",nil];
        
        _manager.responseSerializer = serializer;
    }
    return _manager;
}

- (NSURLSessionDataTask *)dataTask {

    if (_dataTask == nil) {
        
        NSURL *url = [NSURL URLWithString:self.status.VideoUrl];
          
        //2.创建请求对象
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

        YWLog(@"self.status.fullPath：%@",self.status.fullPath);
        
        self.status.currentSize = [self getFileSizeWithFullPath:self.status.fullPath];

        //3 设置请求头信息,告诉服务器请求那一部分数据
        NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.status.currentSize];
        [request setValue:range forHTTPHeaderField:@"Range"];
        
        MJWeakSelf

#pragma mark - //完成之后要做的事
        _dataTask = [self.manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {

            //关闭文件句柄
            [weakSelf.handle closeFile];
            weakSelf.handle = nil;
            
            YWLog(@"%@",error);
            
            if (error == nil) {
                
                //1、改枚举状态
                weakSelf.status.downloadType = YWDownloadType_Finish;
                
                //2、数据库
                //移除正在中的数据库、再添加到完成了的数据库
                [YWDownloadDataBaseTool removeDownloadingStatus:weakSelf.status];
                [YWDownloadDataBaseTool addFinishStatus:weakSelf.status];
                
                NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
                [mainQueue addOperationWithBlock:^{

                    //3、发送通知
                    NSDictionary *userInfo = @{YWDownloadStatusKey:weakSelf.status};
                    [[NSNotificationCenter defaultCenter] postNotificationName:YWFinishDownloadNote object:weakSelf userInfo:userInfo];
                    
                }];
                
            }
            else{
                
                //1、改枚举状态
                weakSelf.status.downloadType = YWDownloadType_Error;
                
                //2、数据库
                //更新正在中的数据库
                [YWDownloadDataBaseTool updateDownloadingStatus:weakSelf.status];
                
               NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
                [mainQueue addOperationWithBlock:^{
                    //3、发送通知
                    NSDictionary *userInfo = @{YWDownloadStatusKey:weakSelf.status};
                    [[NSNotificationCenter defaultCenter] postNotificationName:YWErrorDownloadNote object:weakSelf userInfo:userInfo];
                   
                }];

            }

        }];

#pragma mark - //第一次收到服务器的响应的block
        [self.manager setDataTaskDidReceiveResponseBlock:^NSURLSessionResponseDisposition(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSURLResponse * _Nonnull response) {
           
            NSURL *url = response.URL;
            NSLog(@"url:%@",url);
            
            //1、获得文件的总大小
            //expectedContentLength 本次请求的数据大小
            //这里设置totalSize、currentSize在发起开启下载的时候已经设置过这里不需要重复设置了
            weakSelf.status.totalSize = response.expectedContentLength + weakSelf.status.currentSize;
           
            //2、假如currentSize是零即一点数据根本不存在都没有就要创建一个文件了
            if (weakSelf.status.currentSize == 0) {
                //创建空的文件
                [[NSFileManager defaultManager]createFileAtPath:weakSelf.status.fullPath contents:nil attributes:nil];
            }
            
            //3、创建文件句柄
            weakSelf.handle = [NSFileHandle fileHandleForWritingAtPath:weakSelf.status.fullPath];
            
            //4、移动指针
            [weakSelf.handle seekToEndOfFile];
            
            //枚举
            weakSelf.status.downloadType = YWDownloadType_Downloading;
            
            //5、数据库
            //更新正在中的数据库
            [YWDownloadDataBaseTool updateDownloadingStatus:weakSelf.status];
            
            NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
             [mainQueue addOperationWithBlock:^{
                 //6、发送通知
                 NSDictionary *userInfo = @{YWDownloadStatusKey:weakSelf.status};
                 [[NSNotificationCenter defaultCenter] postNotificationName:YWStartDownloadNote object:weakSelf userInfo:userInfo];
                
             }];
            
            return NSURLSessionResponseAllow;
        }];

        
#pragma mark - //收到服务器返回的数据的block
        [self.manager setDataTaskDidReceiveDataBlock:^(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSData * _Nonnull data) {
            
            //1、写入数据到文件
            [weakSelf.handle writeData:data];
            
            //2、计算文件的下载进度
        //    weakSelf.status.currentSize += data.length; //不用这个、用这个根据fullPath获取更合理更准确
            weakSelf.status.currentSize = [weakSelf getFileSizeWithFullPath:weakSelf.status.fullPath];
            
            NSLog(@"%f",1.0 * weakSelf.status.currentSize / weakSelf.status.totalSize);
            
            
            //从数据库中拿出模型数组/模型、重新设置currentSize后再保存
            
            //3、数据库
            //更新正在中的数据库
            [YWDownloadDataBaseTool updateDownloadingStatus:weakSelf.status];
            

//            //4、获取主线程，不然无法正确显示进度。
//            NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
//            [mainQueue addOperationWithBlock:^{
//                //。。。暂时不需要操作、也不做发送通知。。。
//                
//                CGFloat size = 1.0 * weakSelf.status.currentSize / weakSelf.status.totalSize;
//                NSDictionary *userInfo = @{@"size":@(size),@"url":weakSelf.status.VideoUrl,@"currentSize":@(weakSelf.status.currentSize)};
//                    [[NSNotificationCenter defaultCenter] postNotificationName:@"ceshi" object:weakSelf userInfo:userInfo];
//                
//                
//            }];

        }];

    }

    return _dataTask;

}


//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//------//---//---//---//---//


-(void)setStatus:(YWDownloadStatus *)status{
    
    //设置首次开始下载的时间
    if (status.joinDownloadDate == nil) {
        
        status.joinDownloadDate = [YWDownloadStatus dateToString:[NSDate date]];
    }
       
    _status = status;
    
}


//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//------//---//---//---//---//


//创建了一个任务
//-(void)createDataTask{
//
//    [self.dataTask resume];
//
//    //处理数据库
//    YWDownloadStatus *downloadStatus = [YWDownloadDataBaseTool getDownloadingStatusWithVideoUrl:self.status.VideoUrl];
//
//    if (downloadStatus == nil) { //假如数据库为空、就是添加到数据库
//
//        [YWDownloadDataBaseTool addDownloadingStatus:self.status];
//    }
//    else{ //假如数据库不为空、就是更新数据库
//
//        [YWDownloadDataBaseTool updateDownloadingStatus:self.status];
//    }
//
//    //发送通知
//    NSDictionary *userInfo = @{YWDownloadStatusKey:self.status};
//    [[NSNotificationCenter defaultCenter] postNotificationName:YWResumeDownloadNote object:self userInfo:userInfo];
//
//}


//创建了一个等待任务
//-(void)createWaitingDataTask{
//
//    //处理数据库 （全新的所以肯定是添加不是更新数据库的）
//    [YWDownloadDataBaseTool addDownloadingStatus:self.status];
//
//    //发送通知
//    NSDictionary *userInfo = @{YWDownloadStatusKey:self.status};
//    [[NSNotificationCenter defaultCenter] postNotificationName:YWPauseDownloadNote object:self userInfo:userInfo];
//
//}



//继续一个任务
//-(void)continueDataTask{
//
//    [self.dataTask resume];
//
//    //处理数据库
//    [YWDownloadDataBaseTool updateDownloadingStatus:self.status];
//
//    //发送通知
//    NSDictionary *userInfo = @{YWDownloadStatusKey:self.status};
//    [[NSNotificationCenter defaultCenter] postNotificationName:YWResumeDownloadNote object:self userInfo:userInfo];
//
//}


//将create和continue合并成一个方法，开启/继续一个任务
-(void)resumeDataTask{
    
    [self.dataTask resume];
    
}

//暂停一个任务
-(void)pauseDataTask{
    
    [self.dataTask suspend];
    
//    //处理数据库
//    [YWDownloadDataBaseTool updateDownloadingStatus:self.status];
//
//    //发送通知
//    NSDictionary *userInfo = @{YWDownloadStatusKey:self.status};
//    [[NSNotificationCenter defaultCenter] postNotificationName:YWPauseDownloadNote object:self userInfo:userInfo];
    
}

//删除了一个任务
-(void)removeDataTask{
    
    [self.dataTask cancel];
    self.dataTask = nil;
    
    //移除文件
    NSError *error2 = nil;
    if ([[NSFileManager defaultManager] fileExistsAtPath:self.status.fullPath]) {
         [[NSFileManager defaultManager] removeItemAtPath:self.status.fullPath error:&error2];
        if (error2 == nil) {
            YWLog(@"移除无效视频文件成功");
        }
        else{
            YWLog(@"移除无效视频文件失败");
        }
    }
    
    //处理数据库
//    [YWDownloadDataBaseTool removeDownloadingStatus:self.status];
//
//    //发送通知
//    NSDictionary *userInfo = @{YWDownloadStatusKey:self.status};
//    [[NSNotificationCenter defaultCenter] postNotificationName:YWRemoveDownloadNote object:self userInfo:userInfo];
}


//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//---//------//---//---//---//---//


-(void)dealloc
{
    //清理工作
    //finishTasksAndInvalidate
    [self.manager invalidateSessionCancelingTasks:YES];
}

//传入本地路径获取文件大小
-(NSInteger)getFileSizeWithFullPath:(NSString *)fullPath{
    
    //获得指定文件路径对应文件的数据大小
    NSDictionary *fileInfoDict = [[NSFileManager defaultManager]attributesOfItemAtPath:fullPath error:nil];
    
    NSLog(@"fullPath: %@",fullPath);
    
    NSLog(@"%@",fileInfoDict);
    NSInteger currentSize = [fileInfoDict[@"NSFileSize"] integerValue];
    
    return currentSize;
}

@end
